// FileSystem/image-processor.js
import multer from 'multer';
import path from 'path';
import FileStreamManager from './file-stream-manager.js';

// 创建文件流管理器实例
const fileManager = new FileStreamManager({
  baseDir: 'uploads' // 设置基础目录为uploads
});

/** cb(null, finalFilename); 参数(错误处理-会中断文件上传，最终文件名) */
// 配置multer存储
const storage = multer.diskStorage({
  destination: async (req, file, cb) => {
    try {
      // 确保上传目录存在
      await fileManager.ensureDirectoryExists(fileManager.baseDir);
      cb(null, fileManager.baseDir);
    } catch (err) {
      cb(new Error('服务器存储不可用'));
    }
  },
  filename: async (req, file, cb) => {
    try {
      console.log(file);
      // 中文乱码处理，并存储到 req.file
      const originalname = sanitizeFilename(file.originalname);
      file.originalname = originalname;
      // 生成新文件名（带时间戳和随机数，防止冲突）
      const ext = path.extname(originalname).toLowerCase();
      const basename = path.basename(originalname, ext)
        .replace(/\s+/g, '_')
        .slice(0, 100); // 限制长度
      const finalFilename = `${basename}_${Date.now()}_${Math.random()
        .toString(36)
        .slice(2, 8)}${ext}`;
      // 使用最终文件名
      cb(null, finalFilename);
    } catch (err) {
      console.error('文件名处理失败，使用随机名称:', err);
      cb(null, `file_${Date.now()}.dat`);
    }
  }
});

// 文件类型过滤
const fileFilter = (req, file, cb) => {
  try {
    // MIME类型检查
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'];
    const isValidType = allowedTypes.includes(file.mimetype);

    // 扩展名双重验证
    const ext = path.extname(file.originalname).toLowerCase();
    const isValidExt = ['.jpg', '.jpeg', '.png', '.gif', '.svg'].includes(ext);

    if (isValidType && isValidExt) {
      cb(null, true);
    } else {
      cb(new Error(`文件类型[${file.mimetype}]或扩展名[${ext}]不被允许`), false);
    }
  } catch (err) {
    cb(new Error('文件验证失败'), false);
  }
};

// 上传配置
export const upload = multer({
  storage,
  fileFilter,
  limits: {
    fileSize: 1024 * 1024 * 5, // 5MB限制
    files: 5, // 最多5个文件
    fields: 10 // 最多10个字段
  }
});

// 解码文件名
export const decodeFilename = (filename) => {
  try {
    return decodeURIComponent(filename);
  } catch (e) {
    console.warn('文件名解码失败:', filename);
    return filename;
  }
};

// 解码和清理文件名
export const sanitizeFilename = (filename) => {
  try {
    // 先尝试从 latin1 转 utf8（处理 Node.js 默认的文件名编码问题）
    let decoded = Buffer.from(filename, 'latin1').toString('utf8');
    // 处理可能的 URI 编码（如前端 encodeURIComponent 过的文件名）
    if (decoded.includes('%')) {
      while (decoded !== decodeURIComponent(decoded)) {
        decoded = decodeURIComponent(decoded);
      }
    }
    // 移除非法字符（安全防护）
    return decoded
      .replace(/[/\\?*:|"<>]/g, '')       // 移除非法文件系统字符
      .replace(/(\.\.\/|\.\/)/g, '')     // 防止路径遍历攻击
      .trim();
  } catch (e) {
    console.warn('文件名解码失败，使用原始名称（已过滤非法字符）:', filename, e);
    return filename.replace(/[/\\?*:|"<>]/g, '').trim(); // 失败时仍过滤危险字符
  }
};

// 文件URL获取（支持CDN）
export const getFileUrl = (filename, options = {}) => {
  const { cdnBase = '' } = options;
  const decodedFilename = decodeFilename(filename);
  return `${cdnBase}/uploads/${encodeURIComponent(decodedFilename)}`;
};

// 文件删除（使用FileStreamManager）
export const deleteFile = async (filepath) => {
  try {
    await fileManager.delete(filepath);
    console.log(`文件删除成功: ${filepath}`);
    return true;
  } catch (err) {
    if (err.code !== 'ENOENT') {
      console.error(`文件删除失败: ${filepath}`, err);
    }
    return false;
  }
};

